Fox's Git Mirrors
docs/oci-registry-stack.md HEAD (ed7be254) Text, 9.04 KB
OCI Registry Stack
Omegon Armory should be installable from any OCI-compatible registry and self-hostable by operators who do not want to depend on Styrene infrastructure.
The rollout has two tracks:
1. GHCR first — publish Armory OCI artifacts to T383838ghcr.io/styrene-lab/omegon-armory/* and verify browse, pull, digest pinning, and signature checks end to end.
2. Self-hosted mirror — provide a zot registry backed by Cloudflare R2, deployable to Kubernetes by anyone.
The GitHub repo remains the human review and contribution surface. OCI registries become the distribution surface.
Goals
• Package extensions, plugins, skills, tones, personas, and agent bundles as versioned OCI artifacts.
• Publish a compact Armory index artifact for browse/search without crawling GitHub directories.
• Support digest-pinned installs.
• Support public anonymous pulls and authenticated pushes.
• Keep the self-hosted registry cheap: R2 storage, no public egress fee, tiny zot deployment.
• Avoid requiring Docker or Podman on the client for installation. Omegon should eventually pull artifacts with a native OCI client.
Non-Goals
• Do not make R2 the first required production registry.
• Do not make Kubernetes required for consuming Armory.
• Do not replace GitHub PR review with direct registry mutation.
• Do not require a container daemon for skill/persona/catalog installs.
Artifact Layout
Recommended public registry layout:
T282828
ghcr.io/styrene-lab/omegon-armory/index:latest
ghcr.io/styrene-lab/omegon-armory/extensions/omegon-browser:0.1.0
ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0
ghcr.io/styrene-lab/omegon-armory/personas/tutor:1.0.0
ghcr.io/styrene-lab/omegon-armory/tones/concise:1.0.0
ghcr.io/styrene-lab/omegon-armory/catalog/styrene.coding-agent:1.0.0
ghcr.io/styrene-lab/omegon-armory/profiles/alpharius:1.0.0
ghcr.io/styrene-lab/omegon-armory/forge-templates/minimal-workstation:1.0.0
Self-hosted mirrors should preserve the path layout:
T282828
registry.example.com/omegon-armory/index:latest
registry.example.com/omegon-armory/skills/security:1.0.0
Artifact Contents
Each non-index artifact is a tar payload containing the same source files that exist in this repo.
Skill:
T282828
plugin.toml
SKILL.md
Persona:
T282828
plugin.toml
PERSONA.md
mind/facts.jsonl
Tone:
T282828
plugin.toml
TONE.md
exemplars/*
Catalog agent:
T282828
agent.toml
agent.pkl
PERSONA.md
mind/facts.jsonl
Profile:
T282828
profile.toml
README.md
LOCK.json
Forge template:
T282828
forge.toml
forge.pkl
README.md
Profiles are meta-packages: they reference other Armory artifacts through dependency metadata instead of copying dependency payloads. See Profile Artifacts.
Forge templates are Pkl-canonical Nex payloads wrapped as Armory OCI artifacts. Armory packages and indexes them; Nex owns evaluation. See Nex Forge Templates in Armory.
Extension artifacts may contain either a native extension archive or metadata that points to the existing extension release artifact. The first implementation should prefer reusing extension release archives rather than repackaging binaries in this repo.
OCI Annotations
Every artifact should include enough annotations for basic registry inspection:
T282828
io.styrene.omegon.kind=skill|persona|tone|extension|agent|profile|forge-template|index
io.styrene.omegon.id=security
io.styrene.omegon.name=Security Review
io.styrene.omegon.description=Security checklist for code review
io.styrene.omegon.version=1.0.0
io.styrene.omegon.min_omegon=0.19.0
io.styrene.omegon.source=https://github.com/styrene-lab/omegon-armory
org.opencontainers.image.source=https://github.com/styrene-lab/omegon-armory
org.opencontainers.image.licenses=MIT
Index Artifact
Omegon should browse a single index artifact instead of listing registry repositories.
Reference:
T282828
ghcr.io/styrene-lab/omegon-armory/index:latest
Payload:
T282828
{
"schema": "dev.styrene.omegon.armory.index.v1",
"generated_at": "2026-05-11T00:00:00Z",
"items": [
{
"kind": "skill",
"id": "security",
"name": "Security Review",
"version": "1.0.0",
"description": "Security checklist for code review",
"category": "security",
"ref": "ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0",
"digest": "sha256:...",
"signature": "cosign"
}
]
}
The index should be generated by CI from repository contents and published after individual artifacts. Consumers should cache it locally and allow digest-pinned installs from any listed item.
GHCR Publishing Flow
Initial CI should prove the whole path with one skill and one catalog agent before broad publishing.
The repository now includes:
• T383838scripts/build-oci-artifacts.py — packages Armory directories into tar payloads and writes T383838dist/oci/index.json.
• T383838scripts/publish-oci-artifacts.py — pushes generated payloads with ORAS and optionally signs with cosign.
• T383838.github/workflows/publish-oci.yml — publishes to GHCR on T383838main and supports manual dry runs.
Expected commands:
T282828
oras push ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0 \\
--artifact-type application/vnd.styrene.omegon.skill.v1+tar \\
--annotation io.styrene.omegon.kind=skill \\
--annotation io.styrene.omegon.id=security \\
--annotation io.styrene.omegon.name="Security Review" \\
security.tar.gz
cosign sign --yes ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0
End-to-end verification:
T282828
oras manifest fetch ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0
cosign verify ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0
oras pull ghcr.io/styrene-lab/omegon-armory/skills/security:1.0.0
Self-Hosted zot + R2
R2 is S3-compatible object storage. zot supplies the OCI Distribution API. The architecture is:
T282828
OCI client
-> registry.example.com
-> zot Deployment in Kubernetes
-> Cloudflare R2 bucket
The deployment in T383838deploy/zot-r2/ is intentionally minimal:
• one zot Deployment
• one ClusterIP Service
• one Secret template for R2 credentials
• one ConfigMap containing T383838config.json
• one optional Ingress template
Operators provide:
• R2 bucket name
• R2 account endpoint
• R2 access key ID
• R2 secret access key
• hostname and TLS policy
• auth policy for pushes
Public pulls can be anonymous. Pushes must be authenticated at the ingress or zot auth layer.
To publish to a self-hosted registry after deploying zot:
T282828
python3 scripts/build-oci-artifacts.py \\
--registry registry.example.com/omegon-armory \\
--out dist/oci
oras login registry.example.com
python3 scripts/publish-oci-artifacts.py --out dist/oci --sign
Cost Model
GHCR is the default because public package usage is currently free and operationally simple.
The R2 mirror exists for cost and control:
• R2 avoids public egress charges.
• Blob storage is cheap and digest-addressed.
• The index is small and cacheable.
• zot can run on a very small Kubernetes node.
The largest avoidable cost is uncontrolled anonymous scraping. Use Cloudflare caching/rate limiting or ingress rate limits if the public mirror becomes popular.
Implementation Phases
Phase 1: GHCR Proof
• Add CI workflow to package one skill as OCI.
• Sign it with cosign keyless signing.
• Publish to GHCR.
• Pull and verify in CI.
• Generate and publish a minimal index artifact.
Phase 2: Full Armory Publish
• Package all skills, personas, tones, catalog agents, profiles, and forge templates.
• Add profile dependency metadata to the generated index.
• Add extension entries that point to release artifacts or repackaged archives.
• Publish multi-item index.
• Add digest checks to generated index.
Phase 3: Omegon Client
• Add T383838armory.registry config.
• Add OCI index fetch and cache.
• Add digest-pinned T383838omegon armory install.
• Verify cosign signatures before install where policy requires it.
• Keep raw GitHub discovery as a fallback during migration.
Phase 4: Self-Hosted Mirror
• Deploy T383838deploy/zot-r2/ to a test Kubernetes namespace.
• Add a local compose stack for zot + static site smoke tests.
• Mirror GHCR artifacts into zot.
• Rewrite the index namespace for the destination registry.
• Verify public pull through custom registry hostname.
• Document backup, lifecycle, auth, and garbage collection.
Open Questions
• Should extension binaries be republished into the Armory namespace, or should extension OCI artifacts only reference release archives?
• Should the index be one artifact per channel (T383838stable, T383838nightly) or one artifact with channels inside the JSON?
• Should self-hosted mirrors be pull-through caches or explicit replicated registries?
• Should official profiles always ship T383838LOCK.json, or should some remain floating by policy?
• Which native Rust OCI client should Omegon use for daemonless pulls?
Served by rngit 1.5.2 - Generated in 0.06s